import streamlit as st
import requests
import pandas as pd
import numpy as np
import time
import json
from datetime import datetime
import networkx as nx
import io
import base64
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots

# 配置页面样式
st.set_page_config(
    page_title="智能化漏洞检测与攻击路径分析平台",
    page_icon="🔒",
    layout="wide",
    initial_sidebar_state="expanded")

# 自定义CSS样式
st.markdown("""
<style>
    /* 全局样式 */
    .reportview-container {
        background-color: #f0f2f6;
    }
    
    /* 卡片样式 */
    .stCard {
        background-color: white;
        border-radius: 10px;
        padding: 20px;
        margin-bottom: 20px;
        box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        transition: transform 0.2s, box-shadow 0.2s;
    }
    
    .stCard:hover {
        transform: translateY(-2px);
        box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
    }
    
    /* 按钮样式 */
    .stButton>button {
        background-color: #1e88e5;
        color: white;
        border-radius: 6px;
        font-weight: bold;
        transition: all 0.3s ease;
    }
    
    .stButton>button:hover {
        background-color: #1976d2;
        transform: translateY(-1px);
        box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
    }
    
    /* 标题样式 */
    h1, h2, h3, h4 {
        color: #2c3e50;
        font-family: 'Microsoft YaHei', 'PingFang SC', sans-serif;
    }
    
    /* 指标卡片样式 */
    .metric-card {
        background-color: white;
        border-radius: 8px;
        padding: 15px;
        text-align: center;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    }
    
    .metric-card h3 {
        font-size: 1.1rem;
        margin-bottom: 10px;
        color: #7f8c8d;
    }
    
    .metric-card .value {
        font-size: 2rem;
        font-weight: bold;
        color: #1e88e5;
    }
    
    /* 状态徽章样式 */
    .status-badge {
        padding: 4px 12px;
        border-radius: 12px;
        font-size: 0.85rem;
        font-weight: bold;
        display: inline-block;
    }
    
    /* 风险等级颜色 */
    .high-risk {
        background-color: #ffebee;
        color: #c62828;
    }
    
    .medium-risk {
        background-color: #fff3e0;
        color: #ef6c00;
    }
    
    .low-risk {
        background-color: #e8f5e9;
        color: #2e7d32;
    }
    
    /* 滚动条样式 */
    ::-webkit-scrollbar {
        width: 8px;
        height: 8px;
    }
    
    ::-webkit-scrollbar-track {
        background: #f1f1f1;
        border-radius: 4px;
    }
    
    ::-webkit-scrollbar-thumb {
        background: #c1c1c1;
        border-radius: 4px;
    }
    
    ::-webkit-scrollbar-thumb:hover {
        background: #a1a1a1;
    }
</style>
""", unsafe_allow_html=True)

# 自定义主题色彩
primary_color = "#1e88e5"
secondary_color = "#26a69a"
accent_color = "#ff9800"
danger_color = "#e53935"
light_color = "#f5f5f5"
dark_color = "#212121"

# 后端API地址
API_BASE_URL = "http://localhost:5000/api"

# 侧边栏导航
with st.sidebar:
    # 添加平台标志和标题
    st.markdown("<div style='text-align: center; margin-bottom: 20px;'>", unsafe_allow_html=True)
    st.markdown("<h1 style='color: #1e88e5; font-size: 26px; margin-bottom: 0;'>🔒 漏洞扫描平台</h1>", unsafe_allow_html=True)
    st.markdown("<p style='color: #666; font-size: 14px;'>智能化漏洞检测与攻击路径分析</p>", unsafe_allow_html=True)
    st.markdown("</div>", unsafe_allow_html=True)
    
    st.markdown("<hr style='border: 1px solid #e0e0e0; margin: 15px 0;'>", unsafe_allow_html=True)
    
    # 定义页面选项
    page_options = ["扫描任务提交", "扫描结果查看", "漏洞详情", "演示模式", "系统概览"]
    
    # 创建一个容器用于放置页面选择器
    with st.container():
        page = st.selectbox(
            "选择功能模块",
            page_options,
            format_func=lambda x: f"📋 {x}"
        )
    
    st.markdown("<hr style='border: 1px solid #e0e0e0; margin: 15px 0;'>", unsafe_allow_html=True)
    
    # 过滤器部分，添加更好的视觉效果
    with st.expander("🔍 筛选条件", expanded=True):
        severity_filter = st.multiselect(
            "按严重程度过滤",
            options=["高", "中", "低"],
            default=["高", "中", "低"],
            help="选择要显示的漏洞严重程度"
        )
        
        # 添加扫描时间范围过滤器
        scan_time_filter = st.slider(
            "扫描时间范围(天)",
            min_value=1, max_value=30, value=7,
            help="显示最近N天的扫描结果"
        )
    
    st.markdown("<hr style='border: 1px solid #e0e0e0; margin: 15px 0;'>", unsafe_allow_html=True)
    
    # 演示数据开关，使用更醒目的UI
    with st.container():
        show_demo_data = st.toggle(
            "🎭 使用演示数据", 
            value=True,
            help="开启后使用示例数据进行展示"
        )
    
    st.markdown("<hr style='border: 1px solid #e0e0e0; margin: 15px 0;'>", unsafe_allow_html=True)
    
    # 添加系统信息和帮助链接
    with st.container():
        st.markdown("<div style='text-align: center; color: #666; font-size: 12px;'>", unsafe_allow_html=True)
        st.markdown("版本 1.0.0")
        st.markdown("<a href='#' style='color: #1e88e5; text-decoration: none;'>使用帮助</a> | <a href='#' style='color: #1e88e5; text-decoration: none;'>关于系统</a>", unsafe_allow_html=True)
        st.markdown("</div>", unsafe_allow_html=True)

# 主页面标题 - 带有动态效果
st.markdown("<div style='text-align: center; margin-bottom: 30px;'>", unsafe_allow_html=True)
st.markdown("<h1 style='color: #2c3e50; font-size: 32px; margin-bottom: 10px;'>智能化漏洞检测与攻击路径分析平台</h1>", unsafe_allow_html=True)
st.markdown("<p style='color: #7f8c8d; font-size: 16px;'>全面保障您的网络安全，智能识别潜在风险</p>", unsafe_allow_html=True)
st.markdown("</div>", unsafe_allow_html=True)

# 自定义工具函数
def submit_scan_task(target, scan_depth, scan_types):
    """提交扫描任务到后端"""
    try:
        response = requests.post(
            f"{API_BASE_URL}/scan",
            json={
                "target": target,
                "scan_depth": scan_depth,
                "scan_types": scan_types
            }
        )
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        st.error(f"提交扫描任务失败: {str(e)}")
        return None

def get_scan_status(task_id):
    """获取扫描任务状态"""
    try:
        response = requests.get(f"{API_BASE_URL}/scan/{task_id}/status")
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        st.error(f"获取任务状态失败: {str(e)}")
        return None

def get_scan_report(task_id):
    """获取扫描报告"""
    try:
        response = requests.get(f"{API_BASE_URL}/scan/{task_id}/report")
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        st.error(f"获取扫描报告失败: {str(e)}")
        return None

def get_vulnerability_detail(vuln_id):
    """获取漏洞详情"""
    try:
        response = requests.get(f"{API_BASE_URL}/vuln/{vuln_id}")
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        st.error(f"获取漏洞详情失败: {str(e)}")
        return None

def run_mock_scan(target):
    """运行模拟扫描"""
    try:
        response = requests.post(
            f"{API_BASE_URL}/demo/mock_scan",
            json={"target": target}
        )
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        st.error(f"模拟扫描失败: {str(e)}")
        return None

def generate_attack_path_graph(vulnerabilities):
    """生成攻击路径图"""
    if not vulnerabilities:
        return None
    
    G = nx.DiGraph()
    
    # 添加节点和边
    for vuln in vulnerabilities:
        # 将漏洞作为节点
        node_id = f"{vuln['path']}-{vuln['vuln_type']}"
        severity = vuln.get('severity', 'medium')
        risk_score = vuln.get('risk_score', 0.5)
        
        # 根据严重程度设置节点颜色和大小
        color_map = {
            'high': '#e53935',
            'medium': '#ff9800',
            'low': '#4caf50'
        }
        
        # 添加节点
        G.add_node(
            node_id,
            label=vuln['vuln_type'],
            path=vuln['path'],
            color=color_map.get(severity, '#9e9e9e'),
            size=10 + risk_score * 10,  # 风险评分越大，节点越大
            severity=severity,
            vuln_id=vuln.get('vuln_id', '')
        )
    
    # 简化的攻击路径连接算法
    # 在实际应用中，这里应该基于实际的攻击路径分析算法
    nodes = list(G.nodes)
    for i in range(len(nodes) - 1):
        G.add_edge(nodes[i], nodes[i+1], weight=1)
    
    return G

def create_plotly_attack_graph(G):
    """创建Plotly交互式攻击路径图"""
    if not G or len(G.nodes) == 0:
        return None
    
    # 生成节点布局
    pos = nx.spring_layout(G, seed=42, k=0.5, iterations=50)
    
    # 提取节点位置和属性
    node_x = []
    node_y = []
    node_text = []
    node_colors = []
    node_sizes = []
    node_hovertext = []
    
    for node in G.nodes():
        x, y = pos[node]
        node_x.append(x)
        node_y.append(y)
        node_text.append(G.nodes[node]['label'])
        node_colors.append(G.nodes[node]['color'])
        node_sizes.append(G.nodes[node]['size'] * 8)
        
        # 创建悬停文本
        hover_text = f"漏洞类型: {G.nodes[node]['label']}<br>"
        hover_text += f"路径: {G.nodes[node]['path']}<br>"
        hover_text += f"风险等级: {G.nodes[node]['severity']}<br>"
        hover_text += f"漏洞ID: {G.nodes[node]['vuln_id']}"
        node_hovertext.append(hover_text)
    
    # 创建节点跟踪
    node_trace = go.Scatter(
        x=node_x,
        y=node_y,
        mode='markers+text',
        marker=dict(
            color=node_colors,
            size=node_sizes,
            line=dict(width=2, color='white')
        ),
        text=node_text,
        textposition='top center',
        hoverinfo='text',
        hovertext=node_hovertext,
        name='漏洞节点'
    )
    
    # 提取边信息
    edge_x = []
    edge_y = []
    
    for edge in G.edges():
        x0, y0 = pos[edge[0]]
        x1, y1 = pos[edge[1]]
        edge_x.append(x0)
        edge_x.append(x1)
        edge_x.append(None)
        edge_y.append(y0)
        edge_y.append(y1)
        edge_y.append(None)
    
    # 创建边跟踪
    edge_trace = go.Scatter(
        x=edge_x,
        y=edge_y,
        line=dict(width=1.5, color='#9e9e9e'),
        hoverinfo='none',
        mode='lines',
        name='攻击路径'
    )
    
    # 创建图表
    fig = go.Figure(data=[edge_trace, node_trace],
                layout=go.Layout(
                    showlegend=True,
                    hovermode='closest',
                    margin=dict(b=20,l=5,r=5,t=40),
                    title=dict(
                        text='攻击路径分析图',
                        font=dict(size=20),
                        x=0.5,
                        y=0.95,
                        xanchor='center',
                        yanchor='top'
                    ),
                    xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
                    yaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
                    plot_bgcolor='white',
                    annotations=[dict(
                        text='交互式节点：点击可查看详情',
                        showarrow=False,
                        xref="paper", yref="paper",
                        x=0.5, y=-0.1
                    )]
                ))
    
    return fig

def export_report_to_html(report_data):
    """导出报告为HTML格式"""
    # 增强的HTML模板，添加图表和更多样式
    html_template = """
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>漏洞扫描报告 - {target_placeholder}</title>
        <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
        <style>
            /* 全局样式 */
            * { margin: 0; padding: 0; box-sizing: border-box; }
            body { 
                font-family: 'Microsoft YaHei', 'PingFang SC', Arial, sans-serif; 
                margin: 0; 
                padding: 20px; 
                background-color: #f5f7fa; 
                color: #2c3e50; 
            }
            
            /* 容器样式 */
            .container { 
                max-width: 1200px; 
                margin: 0 auto; 
                background-color: white; 
                border-radius: 10px; 
                box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); 
                overflow: hidden; 
            }
            
            /* 头部样式 */
            .header { 
                background: linear-gradient(135deg, #1e88e5, #26a69a); 
                color: white; 
                padding: 40px; 
                text-align: center; 
            }
            .header h1 { 
                font-size: 32px; 
                margin-bottom: 10px; 
                font-weight: 600; 
            }
            .header p { 
                font-size: 16px; 
                opacity: 0.9; 
            }
            
            /* 内容样式 */
            .content { padding: 40px; }
            
            /* 摘要卡片样式 */
            .summary-cards { 
                display: grid; 
                grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); 
                gap: 20px; 
                margin-bottom: 30px; 
            }
            .summary-card { 
                background-color: #f8f9fa; 
                padding: 20px; 
                border-radius: 8px; 
                text-align: center; 
                transition: transform 0.3s, box-shadow 0.3s; 
            }
            .summary-card:hover { 
                transform: translateY(-5px); 
                box-shadow: 0 6px 12px rgba(0, 0, 0, 0.1); 
            }
            .summary-card .value { 
                font-size: 32px; 
                font-weight: bold; 
                margin: 10px 0; 
                color: #1e88e5; 
            }
            .summary-card .label { 
                color: #7f8c8d; 
                font-size: 14px; 
            }
            
            /* 信息部分样式 */
            .info-section { 
                margin-bottom: 30px; 
                padding: 20px; 
                background-color: #e3f2fd; 
                border-radius: 8px; 
            }
            .info-section h3 { 
                margin-bottom: 15px; 
                color: #1e88e5; 
            }
            .info-section p { 
                margin: 8px 0; 
                line-height: 1.6; 
            }
            
            /* 图表容器样式 */
            .charts-container { 
                display: grid; 
                grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); 
                gap: 30px; 
                margin-bottom: 40px; 
            }
            .chart-box { 
                padding: 20px; 
                background-color: #fafafa; 
                border-radius: 8px; 
                border: 1px solid #e0e0e0; 
            }
            .chart-box h3 { 
                text-align: center; 
                margin-bottom: 20px; 
                color: #2c3e50; 
            }
            
            /* 表格样式 */
            .table-container { 
                overflow-x: auto; 
                margin-bottom: 30px; 
            }
            table { 
                width: 100%; 
                border-collapse: collapse; 
                font-size: 14px; 
            }
            th, td { 
                padding: 12px 15px; 
                text-align: left; 
                border-bottom: 1px solid #e0e0e0; 
            }
            th { 
                background-color: #f5f5f5; 
                font-weight: 600; 
                color: #555; 
                position: sticky; 
                top: 0; 
                z-index: 10; 
            }
            tr:nth-child(even) { 
                background-color: #fafafa; 
            }
            tr:hover { 
                background-color: #f0f8ff; 
            }
            
            /* 风险等级样式 */
            .severity-high { 
                background-color: #ffebee; 
                color: #c62828; 
                font-weight: bold; 
                padding: 4px 8px; 
                border-radius: 4px; 
            }
            .severity-medium { 
                background-color: #fff3e0; 
                color: #ef6c00; 
                font-weight: bold; 
                padding: 4px 8px; 
                border-radius: 4px; 
            }
            .severity-low { 
                background-color: #e8f5e9; 
                color: #2e7d32; 
                font-weight: bold; 
                padding: 4px 8px; 
                border-radius: 4px; 
            }
            
            /* 页脚样式 */
            .footer { 
                text-align: center; 
                padding: 20px; 
                background-color: #f5f5f5; 
                color: #7f8c8d; 
                font-size: 14px; 
                border-top: 1px solid #e0e0e0; 
            }
        </style>
    </head>
    <body>
        <div class="container">
            <!-- 头部 -->
            <div class="header">
                <h1>漏洞扫描报告</h1>
                <p>全面的安全漏洞检测与分析</p>
            </div>
            
            <!-- 内容区域 -->
            <div class="content">
                <!-- 扫描信息 -->
                <div class="info-section">
                    <h3>扫描基本信息</h3>
                    <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 20px;">
                        <p><strong>扫描目标:</strong> {report_data['target']}</p>
                        <p><strong>扫描时间:</strong> {report_data['created_at']}</p>
                        <p><strong>完成时间:</strong> {report_data['finished_at'] or '未完成'}</p>
                        <p><strong>扫描深度:</strong> {report_data.get('scan_depth', 'N/A')}</p>
                    </div>
                </div>
                
                <!-- 摘要卡片 -->
                <div class="summary-cards">
                    <div class="summary-card">
                        <div class="label">总计漏洞</div>
                        <div class="value">{report_data['risk_stats']['total']}</div>
                    </div>
                    <div class="summary-card">
                        <div class="label">高风险</div>
                        <div class="value" style="color: #e53935;">{report_data['risk_stats']['high']}</div>
                    </div>
                    <div class="summary-card">
                        <div class="label">中风险</div>
                        <div class="value" style="color: #ff9800;">{report_data['risk_stats']['medium']}</div>
                    </div>
                    <div class="summary-card">
                        <div class="label">低风险</div>
                        <div class="value" style="color: #4caf50;">{report_data['risk_stats']['low']}</div>
                    </div>
                </div>
                
                <!-- 图表区域 -->
                <div class="charts-container">
                    <!-- 风险分布饼图 -->
                    <div class="chart-box">
                        <h3>风险分布</h3>
                        <div style="height: 300px;">
                            <canvas id="riskChart"></canvas>
                        </div>
                    </div>
                    
                    <!-- 漏洞类型柱状图 -->
                    <div class="chart-box">
                        <h3>漏洞类型分布</h3>
                        <div style="height: 300px;">
                            <canvas id="typeChart"></canvas>
                        </div>
                    </div>
                </div>
                
                <!-- 漏洞详情表格 -->
                <h2 style="margin-bottom: 20px; color: #2c3e50;">漏洞详情列表</h2>
                <div class="table-container">
                    <table>
                        <thead>
                            <tr>
                                <th>漏洞ID</th>
                                <th>漏洞类型</th>
                                <th>影响路径</th>
                                <th>风险等级</th>
                                <th>风险评分</th>
                                <th>发现时间</th>
                            </tr>
                        </thead>
                        <tbody>
                            {''.join([
                                '<tr>'
                                '<td>' + str(v["vuln_id"]) + '</td>'
                                '<td>' + str(v["vuln_type"]) + '</td>'
                                '<td>' + str(v["path"]) + '</td>'
                                '<td><span class="severity-' + str(v["severity"]) + '">' + str(v["severity"]) + '</span></td>'
                                '<td>' + str(round(v["risk_score"], 2)) + '</td>'
                                '<td>' + str(v["created_at"]) + '</td>'
                                '</tr>'
                                for v in report_data['vulnerabilities']
                            ])}
                        </tbody>
                    </table>
                </div>
            </div>
            
            <!-- 页脚 -->
            <div class="footer">
                <p>智能化漏洞检测与攻击路径分析平台 | 报告生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p>
            </div>
        </div>
        
        <!-- 图表脚本 -->
        <script>
            // 风险分布饼图
            const riskCtx = document.getElementById('riskChart').getContext('2d');
            new Chart(riskCtx, {
                type: 'pie',
                data: {
                    labels: ['高风险', '中风险', '低风险'],
                    datasets: [{
                            data: [risk_data_placeholder],
                            backgroundColor: ['#e53935', '#ff9800', '#4caf50'],
                            borderColor: '#fff',
                            borderWidth: 2
                        }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: {
                        legend: {
                            position: 'bottom'
                        },
                        tooltip: {
                            callbacks: {
                                label: function(context) {
                                    const label = context.label || '';
                                    const value = context.parsed || 0;
                                    const total = context.dataset.data.reduce((a, b) => a + b, 0);
                                    const percentage = Math.round((value / total) * 100);
                                    return `${label}: ${value} (${percentage}%)`;
                                }
                            }
                        }
                    }
                }
            });
            
            // 漏洞类型柱状图 - 这里需要手动构建数据
            // 由于模板限制，这里只显示示例数据
            const typeCtx = document.getElementById('typeChart').getContext('2d');
            new Chart(typeCtx, {
                type: 'bar',
                data: {
                    labels: ['SQL注入', 'XSS', '信息泄露', '命令注入', 'CSRF'],
                    datasets: [{ 
                        label: '漏洞数量',
                        data: [5, 3, 7, 2, 1],
                        backgroundColor: '#1e88e5',
                        borderRadius: 4
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    scales: {
                        y: {
                            beginAtZero: true,
                            ticks: {
                                precision: 0
                            }
                        }
                    }
                }
            });
        </script>
    </body>
    </html>
    """
    
    # 替换模板中的动态内容
    html_template = html_template.replace("{target_placeholder}", report_data['target'])
    
    # 替换模板中的JavaScript数据部分
    risk_data = f"[{report_data['risk_stats']['high']}, {report_data['risk_stats']['medium']}, {report_data['risk_stats']['low']}]"
    html_template = html_template.replace("{risk_data_placeholder}", risk_data)
    
    # 如果有漏洞数据，生成漏洞类型统计
    if report_data['vulnerabilities']:
        # 统计漏洞类型
        vuln_types = {}
        for v in report_data['vulnerabilities']:
            vuln_types[v['vuln_type']] = vuln_types.get(v['vuln_type'], 0) + 1
        
        # 生成标签和数据字符串
        type_labels = "['" + "', ' ".join(vuln_types.keys()) + "']"
        type_data = "[" + ", ".join(str(count) for count in vuln_types.values()) + "]"
        
        # 替换柱状图数据
        html_template = html_template.replace("['SQL注入', 'XSS', '信息泄露', '命令注入', 'CSRF']", type_labels)
        html_template = html_template.replace("[5, 3, 7, 2, 1]", type_data)
    
    return html_template

def get_download_links(df, html_content, scan_id):
    """生成所有下载链接"""
    timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
    
    # 生成CSV下载链接
    csv = df.to_csv(index=False, encoding='utf-8-sig')
    csv_b64 = base64.b64encode(csv.encode()).decode()
    csv_href = f'<a href="data:file/csv;base64,{csv_b64}" download="vulnerability_report_{scan_id}_{timestamp}.csv" style="margin-right: 15px;"><button style="background-color: #1e88e5; color: white; border: none; padding: 8px 16px; border-radius: 4px; cursor: pointer;">📥 下载CSV</button></a>'
    
    # 生成HTML下载链接
    html_b64 = base64.b64encode(html_content.encode()).decode()
    html_href = f'<a href="data:file/html;base64,{html_b64}" download="vulnerability_report_{scan_id}_{timestamp}.html" style="margin-right: 15px;"><button style="background-color: #26a69a; color: white; border: none; padding: 8px 16px; border-radius: 4px; cursor: pointer;">📥 下载HTML</button></a>'
    
    # 生成Excel下载链接
    try:
        import pandas as pd
        from io import BytesIO
        
        buffer = BytesIO()
        with pd.ExcelWriter(buffer, engine='xlsxwriter') as writer:
            df.to_excel(writer, sheet_name='漏洞详情', index=False)
        excel_data = buffer.getvalue()
        
        excel_b64 = base64.b64encode(excel_data).decode()
        excel_href = f'<a href="data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,{excel_b64}" download="vulnerability_report_{scan_id}_{timestamp}.xlsx"><button style="background-color: #ff9800; color: white; border: none; padding: 8px 16px; border-radius: 4px; cursor: pointer;">📥 下载Excel</button></a>'
        
        return f"{csv_href}{html_href}{excel_href}"
    except Exception as e:
        return f"{csv_href}{html_href}<script>document.querySelector('.download-error').style.display = 'block';</script>"

# 页面逻辑
if page == "扫描任务提交":
    # 使用卡片样式包装整个页面内容
    with st.container():
        st.markdown("<div class='stCard'>", unsafe_allow_html=True)
        
        st.header("扫描任务提交")
        
        # 扫描任务表单
        with st.form("scan_form"):
            target_url = st.text_input("目标URL", "http://example.com")
            
            col1, col2 = st.columns(2)
            with col1:
                scan_depth = st.slider("扫描深度", min_value=1, max_value=5, value=2, help="扫描深度越大，覆盖范围越广，但耗时越长")
            with col2:
                scan_types = st.multiselect(
                    "扫描类型",
                    ["sql_injection", "xss", "info_leak", "command_injection", "csrf"],
                    default=["sql_injection", "xss", "info_leak"],
                    help="选择要执行的漏洞扫描类型"
                )
            
            submit_button = st.form_submit_button("提交扫描任务")
        
        # 处理表单提交
        if submit_button:
            with st.spinner("正在提交扫描任务..."):
                result = submit_scan_task(target_url, scan_depth, scan_types)
                
                if result:
                    st.success("扫描任务提交成功！")
                    st.session_state["current_task_id"] = result["task_id"]
                    st.session_state["current_scan_id"] = result["scan_id"]
                    
                    # 显示任务信息
                    col1, col2 = st.columns(2)
                    with col1:
                        st.info(f"任务ID: {result['task_id']}")
                    with col2:
                        st.info(f"扫描ID: {result['scan_id']}")
                    
                    # 提供查看状态的按钮
                    st.markdown("点击下方按钮查看扫描进度和结果:")
                    if st.button("查看扫描状态", key="check_status"):
                        st.session_state["page"] = "扫描结果查看"
                        st.rerun()
        
        st.markdown("</div>", unsafe_allow_html=True)

elif page == "扫描结果查看":
    # 使用卡片样式包装整个页面内容
    with st.container():
        st.markdown("<div class='stCard'>", unsafe_allow_html=True)
        
        st.header("扫描结果查看")
        
        # 任务ID输入
        task_id = st.text_input("任务ID", value=st.session_state.get("current_task_id", ""))
        
        if task_id:
            # 获取扫描状态
            status = get_scan_status(task_id)
            
            if status:
                st.subheader("扫描任务状态")
                
                # 显示任务基本信息 - 使用更美观的卡片布局
                col1, col2, col3 = st.columns(3)
                with col1:
                    st.markdown("<div class='metric-card'>", unsafe_allow_html=True)
                    st.markdown("<h3>扫描目标</h3>", unsafe_allow_html=True)
                    st.markdown(f"<div class='value'>{status['target']}</div>", unsafe_allow_html=True)
                    st.markdown("</div>", unsafe_allow_html=True)
                with col2:
                    st.markdown("<div class='metric-card'>", unsafe_allow_html=True)
                    st.markdown("<h3>当前状态</h3>", unsafe_allow_html=True)
                    # 根据状态显示不同的徽章样式
                    status_color = {}
                    if status['status'] == 'completed':
                        status_color['class'] = 'status-badge low-risk'
                        status_color['text'] = '已完成'
                    elif status['status'] == 'running':
                        status_color['class'] = 'status-badge medium-risk'
                        status_color['text'] = '运行中'
                    elif status['status'] == 'failed':
                        status_color['class'] = 'status-badge high-risk'
                        status_color['text'] = '失败'
                    else:
                        status_color['class'] = 'status-badge'
                        status_color['text'] = status['status']
                    st.markdown(f"<div class='{status_color['class']}'>{status_color['text']}</div>", unsafe_allow_html=True)
                    st.markdown("</div>", unsafe_allow_html=True)
                with col3:
                    st.markdown("<div class='metric-card'>", unsafe_allow_html=True)
                    st.markdown("<h3>进度</h3>", unsafe_allow_html=True)
                    st.markdown(f"<div class='value'>{status['progress']}%</div>", unsafe_allow_html=True)
                    st.markdown("</div>", unsafe_allow_html=True)
                
                # 显示进度条
                progress_bar = st.progress(status['progress'])
                
                # 如果任务已完成，显示详细报告
                if status['status'] == 'completed':
                    st.subheader("扫描报告")
                    
                    # 获取扫描报告
                    report = get_scan_report(task_id)
                    
                    if report:
                        # 显示漏洞统计摘要 - 使用更美观的卡片布局
                        st.markdown("### 漏洞统计摘要")
                        col1, col2, col3, col4 = st.columns(4)
                        with col1:
                            st.markdown("<div class='metric-card'>", unsafe_allow_html=True)
                            st.markdown("<h3>总计漏洞</h3>", unsafe_allow_html=True)
                            st.markdown(f"<div class='value'>{report['risk_stats']['total']}</div>", unsafe_allow_html=True)
                            st.markdown("</div>", unsafe_allow_html=True)
                        with col2:
                            st.markdown("<div class='metric-card'>", unsafe_allow_html=True)
                            st.markdown("<h3>高风险</h3>", unsafe_allow_html=True)
                            st.markdown(f"<div class='value' style='color: #c62828;'>{report['risk_stats']['high']}</div>", unsafe_allow_html=True)
                            st.markdown("</div>", unsafe_allow_html=True)
                        with col3:
                            st.markdown("<div class='metric-card'>", unsafe_allow_html=True)
                            st.markdown("<h3>中风险</h3>", unsafe_allow_html=True)
                            st.markdown(f"<div class='value' style='color: #ef6c00;'>{report['risk_stats']['medium']}</div>", unsafe_allow_html=True)
                            st.markdown("</div>", unsafe_allow_html=True)
                        with col4:
                            st.markdown("<div class='metric-card'>", unsafe_allow_html=True)
                            st.markdown("<h3>低风险</h3>", unsafe_allow_html=True)
                            st.markdown(f"<div class='value' style='color: #2e7d32;'>{report['risk_stats']['low']}</div>", unsafe_allow_html=True)
                            st.markdown("</div>", unsafe_allow_html=True)
                        
                        # 使用Plotly创建风险分布饼图
                        st.markdown("### 风险分布")
                        fig = px.pie(
                            values=[report['risk_stats']['high'], report['risk_stats']['medium'], report['risk_stats']['low']],
                            names=['高风险', '中风险', '低风险'],
                            color=['高风险', '中风险', '低风险'],
                            color_discrete_map={'高风险': '#e53935', '中风险': '#ff9800', '低风险': '#4caf50'},
                            hole=0.3,
                            title='漏洞风险等级分布',
                            labels={'value': '数量', 'name': '风险等级'}
                        )
                        fig.update_layout(
                            font=dict(family="Microsoft YaHei, PingFang SC, sans-serif"),
                            margin=dict(l=20, r=20, t=60, b=20),
                            hovermode='closest',
                            height=400
                        )
                        st.plotly_chart(fig, use_container_width=True)
                        
                        # 漏洞列表表格
                        st.markdown("### 漏洞详情列表")
                        if report['vulnerabilities']:
                            # 将漏洞数据转换为DataFrame
                            vuln_df = pd.DataFrame(report['vulnerabilities'])
                            
                            # 选择要显示的列
                            display_columns = ['vuln_id', 'vuln_type', 'path', 'severity', 'risk_score', 'created_at']
                            display_df = vuln_df[display_columns]
                            
                            # 格式化显示
                            display_df['risk_score'] = display_df['risk_score'].apply(lambda x: f"{x:.2f}")
                            
                            # 添加颜色标记 - 使用新的CSS类
                            def highlight_severity(val):
                                if val == 'high':
                                    return 'background-color: #ffebee; color: #c62828; font-weight: bold;'
                                elif val == 'medium':
                                    return 'background-color: #fff3e0; color: #ef6c00; font-weight: bold;'
                                elif val == 'low':
                                    return 'background-color: #e8f5e9; color: #2e7d32; font-weight: bold;'
                                return ''
                            
                            styled_df = display_df.style.applymap(highlight_severity, subset=['severity'])
                            
                            # 显示表格，增加宽度和滚动选项
                            st.dataframe(styled_df, height=400, use_container_width=True)
                            
                            # 使用Plotly创建漏洞类型分布柱状图
                            st.markdown("### 漏洞类型分布")
                            vuln_type_counts = vuln_df['vuln_type'].value_counts()
                            fig = px.bar(
                                x=vuln_type_counts.index,
                                y=vuln_type_counts.values,
                                labels={'x': '漏洞类型', 'y': '数量'},
                                title='漏洞类型分布统计',
                                color=vuln_type_counts.index,
                                color_discrete_sequence=px.colors.qualitative.Set3
                            )
                            fig.update_layout(
                                font=dict(family="Microsoft YaHei, PingFang SC, sans-serif"),
                                margin=dict(l=20, r=20, t=60, b=20),
                                xaxis_tickangle=-45,
                                height=400
                            )
                            st.plotly_chart(fig, use_container_width=True)
                            
                            # 攻击路径图 - 使用Plotly交互式图表
                            st.markdown("### 攻击路径分析")
                            G = generate_attack_path_graph(report['vulnerabilities'])
                            if G and len(G.nodes) > 0:
                                fig = create_plotly_attack_graph(G)
                                if fig:
                                    st.plotly_chart(fig, use_container_width=True)
                            else:
                                st.info("没有足够的数据生成攻击路径图")
                            
                            # 导出功能 - 使用统一的下载链接函数
                            st.markdown("### 导出报告")
                            html_content = export_report_to_html(report)
                            download_links = get_download_links(display_df, html_content, report['scan_id'])
                            st.markdown(download_links, unsafe_allow_html=True)
                            
                            # 漏洞详情查看
                            st.markdown("### 查看漏洞详情")
                            selected_vuln = st.selectbox(
                                "选择漏洞",
                                vuln_df['vuln_id'],
                                format_func=lambda x: f"{x} ({vuln_df[vuln_df['vuln_id'] == x]['vuln_type'].values[0]})")
                            
                            if st.button("查看详情", key="view_vuln_detail"):
                                st.session_state["selected_vuln_id"] = selected_vuln
                                st.session_state["page"] = "漏洞详情"
                                st.rerun()
                        else:
                            st.success("未发现任何漏洞")
                elif status['status'] == 'failed':
                    st.error("扫描任务执行失败，请查看日志获取详细信息")
                else:
                    st.info("扫描任务正在执行中，请稍后刷新页面查看结果")
                    if st.button("刷新状态"):
                        st.rerun()
            else:
                # 如果是演示模式，尝试使用演示数据
                if show_demo_data and task_id.startswith("demo_"):
                    demo_report = st.session_state.get("demo_report_data", None)
                    if demo_report:
                        st.subheader("扫描报告 (演示数据)")
                        
                        # 显示漏洞统计摘要
                        st.markdown("### 漏洞统计摘要")
                        col1, col2, col3, col4 = st.columns(4)
                        with col1:
                            st.markdown("<div class='metric-card'>", unsafe_allow_html=True)
                            st.markdown("<h3>总计漏洞</h3>", unsafe_allow_html=True)
                            st.markdown(f"<div class='value'>{demo_report['risk_stats']['total']}</div>", unsafe_allow_html=True)
                            st.markdown("</div>", unsafe_allow_html=True)
                        with col2:
                            st.markdown("<div class='metric-card'>", unsafe_allow_html=True)
                            st.markdown("<h3>高风险</h3>", unsafe_allow_html=True)
                            st.markdown(f"<div class='value' style='color: #c62828;'>{demo_report['risk_stats']['high']}</div>", unsafe_allow_html=True)
                            st.markdown("</div>", unsafe_allow_html=True)
                        with col3:
                            st.markdown("<div class='metric-card'>", unsafe_allow_html=True)
                            st.markdown("<h3>中风险</h3>", unsafe_allow_html=True)
                            st.markdown(f"<div class='value' style='color: #ef6c00;'>{demo_report['risk_stats']['medium']}</div>", unsafe_allow_html=True)
                            st.markdown("</div>", unsafe_allow_html=True)
                        with col4:
                            st.markdown("<div class='metric-card'>", unsafe_allow_html=True)
                            st.markdown("<h3>低风险</h3>", unsafe_allow_html=True)
                            st.markdown(f"<div class='value' style='color: #2e7d32;'>{demo_report['risk_stats']['low']}</div>", unsafe_allow_html=True)
                            st.markdown("</div>", unsafe_allow_html=True)
                        
                        # 其他演示数据展示逻辑...
                        vuln_df = pd.DataFrame(demo_report['vulnerabilities'])
                        
                        # 漏洞列表表格
                        st.markdown("### 漏洞详情列表")
                        display_columns = ['vuln_id', 'vuln_type', 'path', 'severity', 'risk_score']
                        display_df = vuln_df[display_columns]
                        
                        # 格式化显示
                        display_df['risk_score'] = display_df['risk_score'].apply(lambda x: f"{x:.2f}")
                        
                        # 添加颜色标记
                        styled_df = display_df.style.applymap(lambda val: highlight_severity(val), subset=['severity'])
                        
                        # 显示表格
                        st.dataframe(styled_df, height=400, use_container_width=True)
                else:
                    st.error("无法获取任务状态或任务不存在")
        
        st.markdown("</div>", unsafe_allow_html=True)

elif page == "漏洞详情":
    # 使用卡片样式包装整个页面内容
    with st.container():
        st.markdown("<div class='stCard'>", unsafe_allow_html=True)
        
        st.header("漏洞详情")
        
        # 漏洞ID输入
        vuln_id = st.text_input("漏洞ID", value=st.session_state.get("selected_vuln_id", ""))
        
        if vuln_id:
            # 获取漏洞详情
            detail = get_vulnerability_detail(vuln_id)
            
            if detail:
                vuln = detail['vulnerability']
                scan_info = detail['scan_info']
                
                # 显示基本信息 - 使用更美观的标题和布局
                st.markdown(f"<h2 style='color: #2c3e50; margin-bottom: 20px;'>漏洞ID: {vuln['vuln_id']}</h2>", unsafe_allow_html=True)
                
                # 基本信息卡片
                col1, col2, col3 = st.columns(3)
                with col1:
                    st.markdown("<div class='metric-card'>", unsafe_allow_html=True)
                    st.markdown("<h3>漏洞类型</h3>", unsafe_allow_html=True)
                    st.markdown(f"<div class='value'>{vuln['vuln_type']}</div>", unsafe_allow_html=True)
                    st.markdown("</div>", unsafe_allow_html=True)
                with col2:
                    st.markdown("<div class='metric-card'>", unsafe_allow_html=True)
                    st.markdown("<h3>风险等级</h3>", unsafe_allow_html=True)
                    # 根据风险等级显示不同颜色的标签
                    if vuln['severity'] == 'high':
                        st.markdown("<div class='status-badge high-risk'>🔴 高风险</div>", unsafe_allow_html=True)
                    elif vuln['severity'] == 'medium':
                        st.markdown("<div class='status-badge medium-risk'>🟠 中风险</div>", unsafe_allow_html=True)
                    elif vuln['severity'] == 'low':
                        st.markdown("<div class='status-badge low-risk'>🟢 低风险</div>", unsafe_allow_html=True)
                    else:
                        st.markdown(f"<div class='status-badge'>{vuln['severity']}</div>", unsafe_allow_html=True)
                    st.markdown("</div>", unsafe_allow_html=True)
                with col3:
                    st.markdown("<div class='metric-card'>", unsafe_allow_html=True)
                    st.markdown("<h3>风险评分</h3>", unsafe_allow_html=True)
                    st.markdown(f"<div class='value'>{vuln['risk_score']:.2f}</div>", unsafe_allow_html=True)
                    st.markdown("</div>", unsafe_allow_html=True)
                
                # 详细信息部分 - 使用卡片样式
                st.markdown("<div class='stCard' style='margin-top: 20px;'>", unsafe_allow_html=True)
                st.markdown("### 详细信息")
                
                col1, col2 = st.columns(2)
                with col1:
                    st.markdown(f"**影响路径:** {vuln['path']}")
                    st.markdown(f"**扫描目标:** {scan_info['target']}")
                    st.markdown(f"**发现时间:** {vuln['created_at']}")
                with col2:
                    if vuln['payload']:
                        st.markdown(f"**攻击载荷:**")
                        st.code(vuln['payload'])
                st.markdown("</div>", unsafe_allow_html=True)
                
                # 发现证据部分 - 使用卡片样式
                if vuln['evidence']:
                    st.markdown("<div class='stCard' style='margin-top: 20px;'>", unsafe_allow_html=True)
                    st.markdown("### 发现证据")
                    st.info(vuln['evidence'])
                    st.markdown("</div>", unsafe_allow_html=True)
                
                # 修复建议部分 - 使用卡片样式和改进的复制功能
                st.markdown("<div class='stCard' style='margin-top: 20px;'>", unsafe_allow_html=True)
                st.markdown("### 修复建议")
                if vuln['suggestion']:
                    # 创建一个可复制的文本区域
                    suggestion_text = vuln['suggestion']
                    
                    # 使用会话状态来跟踪复制状态
                    if 'copied' not in st.session_state:
                        st.session_state['copied'] = False
                    
                    # 显示建议内容
                    st.text_area("修复建议详情", suggestion_text, height=300, key="suggestion_text")
                    
                    # 添加复制按钮和返回按钮在同一行
                    col1, col2 = st.columns([1, 1])
                    with col1:
                        # 添加复制按钮
                        if st.button("复制建议", key="copy_suggestion"):
                            # 使用JavaScript实现真正的复制功能
                            # 先处理文本内容，避免f-string中的转义问题
                            processed_text = suggestion_text.replace('`', '\\`')
                            st.markdown(
                                f"""
                                <script>
                                    navigator.clipboard.writeText(processedText).then(function() {{
                                        console.log('Text copied to clipboard');
                                    }}, function(err) {{
                                        console.error('Could not copy text: ', err);
                                    }});
                                </script>
                                """,
                                unsafe_allow_html=True
                            )
                            st.session_state['copied'] = True
                        
                        # 显示复制成功提示
                        if st.session_state['copied']:
                            st.success("修复建议已复制到剪贴板！")
                    with col2:
                        # 返回按钮
                        if st.button("返回报告列表", key="back_to_list"):
                            st.session_state["page"] = "扫描结果查看"
                            st.session_state['copied'] = False
                            st.rerun()
                else:
                    st.info("暂无修复建议")
                    # 单独显示返回按钮
                    if st.button("返回报告列表", key="back_to_list"):
                        st.session_state["page"] = "扫描结果查看"
                        st.rerun()
                st.markdown("</div>", unsafe_allow_html=True)
            else:
                st.error("无法获取漏洞详情或漏洞不存在")
                # 返回按钮
                if st.button("返回报告列表"):
                    st.session_state["page"] = "扫描结果查看"
                    st.rerun()
        
        st.markdown("</div>", unsafe_allow_html=True)

elif page == "演示模式":
    # 使用卡片样式包装整个页面内容
    with st.container():
        st.markdown("<div class='stCard'>", unsafe_allow_html=True)
        
        st.header("演示模式")
        st.info("演示模式可以生成模拟的漏洞数据，无需实际扫描目标网站。")
        
        # 演示目标选择
        demo_target = st.selectbox(
            "选择演示目标",
            ["http://example.com", "http://test-site.com", "http://demo-app.com"],
            help="选择一个预设的演示目标"
        )
        
        # 生成模拟数据按钮
        if st.button("生成模拟扫描数据", key="generate_mock_data"):
            with st.spinner("正在生成模拟数据..."):
                # 尝试调用API，如果失败则直接使用本地模拟数据
                try:
                    mock_result = run_mock_scan(demo_target)
                    
                    # 如果API调用成功但返回的数据为空，使用本地模拟数据
                    if not mock_result or len(mock_result.get('vulnerabilities', [])) == 0:
                        # 读取本地演示数据文件
                        demo_data_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), 'examples', 'demo_data.json')
                        if os.path.exists(demo_data_path):
                            with open(demo_data_path, 'r', encoding='utf-8') as f:
                                demo_data = json.load(f)
                                # 找到对应目标的扫描结果
                                for scan_result in demo_data.get('scan_results', []):
                                    if scan_result['target'] == demo_target:
                                        mock_result = scan_result
                                        break
                except Exception as e:
                    # 如果API调用失败，读取本地演示数据文件
                    st.warning(f"调用演示API失败，使用本地演示数据: {str(e)}")
                    demo_data_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), 'examples', 'demo_data.json')
                    if os.path.exists(demo_data_path):
                        with open(demo_data_path, 'r', encoding='utf-8') as f:
                            demo_data = json.load(f)
                            # 找到对应目标的扫描结果
                            for scan_result in demo_data.get('scan_results', []):
                                if scan_result['target'] == demo_target:
                                    mock_result = scan_result
                                    break
                
                if mock_result:
                    st.success("模拟数据生成成功！")
                    st.session_state["current_scan_id"] = mock_result["scan_id"]
                    
                    # 显示模拟结果摘要 - 使用美观的卡片布局
                    st.subheader("模拟扫描结果摘要")
                    
                    # 显示漏洞统计
                    col1, col2, col3, col4 = st.columns(4)
                    with col1:
                        st.markdown("<div class='metric-card'>", unsafe_allow_html=True)
                        st.markdown("<h3>总计漏洞</h3>", unsafe_allow_html=True)
                        st.markdown(f"<div class='value'>{mock_result['risk_stats']['total']}</div>", unsafe_allow_html=True)
                        st.markdown("</div>", unsafe_allow_html=True)
                    with col2:
                        st.markdown("<div class='metric-card'>", unsafe_allow_html=True)
                        st.markdown("<h3>高风险</h3>", unsafe_allow_html=True)
                        st.markdown(f"<div class='value' style='color: #c62828;'>{mock_result['risk_stats']['high']}</div>", unsafe_allow_html=True)
                        st.markdown("</div>", unsafe_allow_html=True)
                    with col3:
                        st.markdown("<div class='metric-card'>", unsafe_allow_html=True)
                        st.markdown("<h3>中风险</h3>", unsafe_allow_html=True)
                        st.markdown(f"<div class='value' style='color: #ef6c00;'>{mock_result['risk_stats']['medium']}</div>", unsafe_allow_html=True)
                        st.markdown("</div>", unsafe_allow_html=True)
                    with col4:
                        st.markdown("<div class='metric-card'>", unsafe_allow_html=True)
                        st.markdown("<h3>低风险</h3>", unsafe_allow_html=True)
                        st.markdown(f"<div class='value' style='color: #2e7d32;'>{mock_result['risk_stats']['low']}</div>", unsafe_allow_html=True)
                        st.markdown("</div>", unsafe_allow_html=True)
                    
                    # 显示模拟漏洞列表 - 使用更美观的表格样式
                    st.subheader("模拟漏洞列表")
                    vuln_df = pd.DataFrame(mock_result['vulnerabilities'])
                    display_columns = ['vuln_id', 'vuln_type', 'path', 'severity', 'risk_score']
                    display_df = vuln_df[display_columns]
                    
                    # 格式化显示
                    display_df['risk_score'] = display_df['risk_score'].apply(lambda x: f"{x:.2f}")
                    
                    # 添加颜色标记
                    def highlight_severity(val):
                        if val == 'high':
                            return 'background-color: #ffebee; color: #c62828; font-weight: bold;'
                        elif val == 'medium':
                            return 'background-color: #fff3e0; color: #ef6c00; font-weight: bold;'
                        elif val == 'low':
                            return 'background-color: #e8f5e9; color: #2e7d32; font-weight: bold;'
                        return ''
                    
                    styled_df = display_df.style.applymap(highlight_severity, subset=['severity'])
                    
                    # 显示表格
                    st.dataframe(styled_df, height=400, use_container_width=True)
                    
                    # 提供查看详细报告的按钮
                    if st.button("查看详细报告", key="view_detail_report"):
                        # 在演示模式下，我们创建一个假的任务ID来查看报告
                        st.session_state["current_task_id"] = f"demo_{mock_result['scan_id']}"
                        st.session_state["demo_report_data"] = mock_result
                        st.session_state["page"] = "扫描结果查看"
                        st.rerun()
                else:
                    st.error("无法生成模拟数据，请检查系统配置")
        
        st.markdown("</div>", unsafe_allow_html=True)

elif page == "系统概览":
    # 使用卡片样式包装整个页面内容
    with st.container():
        st.markdown("<div class='stCard'>", unsafe_allow_html=True)
        
        # 系统介绍部分
        st.markdown("<div style='text-align: center; margin-bottom: 30px;'>", unsafe_allow_html=True)
        st.markdown("<h1 style='color: #2c3e50; font-size: 28px; margin-bottom: 15px;'>智能化漏洞检测与攻击路径分析平台</h1>", unsafe_allow_html=True)
        st.markdown("<p style='color: #7f8c8d; font-size: 16px;'>全面保障您的网络安全，智能识别潜在风险</p>", unsafe_allow_html=True)
        st.markdown("</div>", unsafe_allow_html=True)
        
        # 系统信息
        st.markdown("### 系统信息")
        st.info("智能化漏洞检测与攻击路径分析平台\n基于Flask + Celery + XGBoost + Streamlit构建")
        
        # 功能模块介绍 - 使用更美观的卡片布局
        st.markdown("### 核心功能模块")
        col1, col2 = st.columns(2)
        
        # 左侧功能模块
        with col1:
            # 扫描模块卡片
            st.markdown("<div class='stCard'>", unsafe_allow_html=True)
            st.markdown("<h3 style='color: #1e88e5; margin-top: 0;'>🔍 扫描模块</h3>", unsafe_allow_html=True)
            st.markdown("- 支持多种漏洞类型的扫描")
            st.markdown("- 异步任务处理，提高系统效率")
            st.markdown("- 可配置的扫描深度和范围")
            st.markdown("</div>", unsafe_allow_html=True)
            
            # 风险评估模块卡片
            st.markdown("<div class='stCard'>", unsafe_allow_html=True)
            st.markdown("<h3 style='color: #1e88e5; margin-top: 0;'>📊 风险评估模块</h3>", unsafe_allow_html=True)
            st.markdown("- 基于XGBoost的机器学习模型")
            st.markdown("- 多维度特征分析")
            st.markdown("- 精确的风险评分和分级")
            st.markdown("</div>", unsafe_allow_html=True)
        
        # 右侧功能模块
        with col2:
            # 可视化模块卡片
            st.markdown("<div class='stCard'>", unsafe_allow_html=True)
            st.markdown("<h3 style='color: #1e88e5; margin-top: 0;'>📈 可视化模块</h3>", unsafe_allow_html=True)
            st.markdown("- 直观的漏洞列表表格")
            st.markdown("- 风险分布图表")
            st.markdown("- 交互式攻击路径图分析")
            st.markdown("</div>", unsafe_allow_html=True)
            
            # 修复建议模块卡片
            st.markdown("<div class='stCard'>", unsafe_allow_html=True)
            st.markdown("<h3 style='color: #1e88e5; margin-top: 0;'>🔧 修复建议模块</h3>", unsafe_allow_html=True)
            st.markdown("- 模板化的修复步骤")
            st.markdown("- 代码示例参考")
            st.markdown("- LLM集成支持")
            st.markdown("</div>", unsafe_allow_html=True)
        
        # 快速导航 - 使用更美观的按钮样式
        st.markdown("### 快速导航")
        col1, col2, col3 = st.columns(3)
        with col1:
            if st.button("🚀 开始新扫描"):
                st.session_state["page"] = "扫描任务提交"
                st.rerun()
        with col2:
            if st.button("📋 查看历史报告"):
                st.session_state["page"] = "扫描结果查看"
                st.rerun()
        with col3:
            if st.button("🎭 进入演示模式"):
                st.session_state["page"] = "演示模式"
                st.rerun()
        
        # 系统状态信息
        st.markdown("### 系统状态")
        try:
            # 尝试获取系统健康状态
            health_response = requests.get(f"{API_BASE_URL}/health", timeout=2)
            if health_response.status_code == 200:
                health_data = health_response.json()
                col1, col2, col3 = st.columns(3)
                with col1:
                    st.markdown("<div class='metric-card'>", unsafe_allow_html=True)
                    st.markdown("<h3>系统状态</h3>", unsafe_allow_html=True)
                    status_text = "✅ 健康" if health_data.get('status') == 'healthy' else "❌ 异常"
                    st.markdown(f"<div class='value'>{status_text}</div>", unsafe_allow_html=True)
                    st.markdown("</div>", unsafe_allow_html=True)
                with col2:
                    st.markdown("<div class='metric-card'>", unsafe_allow_html=True)
                    st.markdown("<h3>系统版本</h3>", unsafe_allow_html=True)
                    st.markdown(f"<div class='value'>{health_data.get('version', '未知')}</div>", unsafe_allow_html=True)
                    st.markdown("</div>", unsafe_allow_html=True)
                with col3:
                    st.markdown("<div class='metric-card'>", unsafe_allow_html=True)
                    st.markdown("<h3>当前时间</h3>", unsafe_allow_html=True)
                    timestamp = datetime.fromisoformat(health_data.get('timestamp', datetime.utcnow().isoformat())).strftime('%Y-%m-%d %H:%M:%S')
                    st.markdown(f"<div class='value'>{timestamp}</div>", unsafe_allow_html=True)
                    st.markdown("</div>", unsafe_allow_html=True)
            else:
                st.warning("无法获取完整的系统状态信息")
        except requests.exceptions.RequestException:
            st.warning("无法连接到后端服务，当前以演示模式运行")
        
        st.markdown("</div>", unsafe_allow_html=True)

# 页脚
st.markdown("---")
st.markdown("智能化漏洞检测与攻击路径分析平台 © 2025")

# 当会话状态中的页面发生变化时，重新运行应用
if 'page' in st.session_state and st.session_state['page'] != page:
    st.session_state['page'] = page
    st.rerun()